﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharedLib.XmlDataModel;
using System.Collections.ObjectModel;
using System.Xml;
using SharedLib.Helpers;

namespace Tracy.DataModel
{
    public class FilterSet:XmlDataModelWithAttributes
    {
        public FilterSet() : base() { }
        public FilterSet(XmlNode node) : base(node) { }

        private SortedSet<FanSubGroup> _fanSubGroups;

        public SortedSet<FanSubGroup> FanSubGroups
        {
            get { if (_fanSubGroups == null)_fanSubGroups = new SortedSet<FanSubGroup>(); return _fanSubGroups; }
            set { _fanSubGroups = value; }
        }

        private Format _format;

        public Format Format
        {
            get { return _format; }
            set {
                Properties["format"] = value.Name;
                _format = value; 
            }
        }

        private Resolution _resolution;

        public Resolution Resolution
        {
            get { return _resolution; }
            set 
            {
                Properties["resolution"] = value.Name;
                _resolution = value; 
            }
        }

        private FeedSource _feedSource;

        public FeedSource FeedSource
        {
            get { return _feedSource; }
            set {
                Properties["feed-source"] = value.Name;
                _feedSource = value; }
        }

        protected override XmlElement GenerateXmlNode(XmlDocument doc)
        {
            XmlElement rootNode = base.GenerateXmlNode(doc);
            if (FanSubGroups.Count > 0)
            {
                XmlElement fanSubGroupsNode = doc.CreateElement("fan-sub-groups");
                foreach (FanSubGroup fanSubGroup in FanSubGroups)
                {
                    fanSubGroupsNode.AppendChild(XmlHelper.CreateElementWithTextValue("fan-sub-group", fanSubGroup.Name, doc));
                }
                rootNode.AppendChild(fanSubGroupsNode);
            }

            return rootNode;
        }

        protected override void ParseRootNode(XmlElement rootNode)
        {
            base.ParseRootNode(rootNode);
            foreach (string fanSubGroupName in XmlHelper.GetNodeValues(rootNode, "fan-sub-groups/fan-sub-group"))
            {
                FanSubGroups.Add(TracyFacade.Instance.FilterManager.FanSubGroupProvider.GetItemByName(fanSubGroupName));
            }

            string format = XmlHelper.GetNodeValue(rootNode, "format");
            if (!String.IsNullOrEmpty(format)) Format = TracyFacade.Instance.FilterManager.FormatProvider.GetItemByName(format);

            string resolution = XmlHelper.GetNodeValue(rootNode, "resolution");
            if (!String.IsNullOrEmpty(resolution)) Resolution = TracyFacade.Instance.FilterManager.ResolutionProvider.GetItemByName(resolution);

            string feedSource = XmlHelper.GetNodeValue(rootNode, "feed-source");
            if (!String.IsNullOrEmpty(feedSource)) FeedSource = TracyFacade.Instance.FilterManager.FeedSourceProvider.GetItemByName(feedSource);
        }

        public override string RootNodeName
        {
            get
            {
                return "filter-set";
            }
        }

        public bool Equals(FilterSet anotherFilterSet)
        {
            //TODO: Use ID to compare
            
            //Compare Source
            if (!IsEqual(FeedSource, anotherFilterSet.FeedSource)) return false;

            //Compare FanSubGroups
            if (anotherFilterSet.FanSubGroups.Count != FanSubGroups.Count) return false;
            SortedSet<FanSubGroup>.Enumerator e = FanSubGroups.GetEnumerator();
            SortedSet<FanSubGroup>.Enumerator ae = anotherFilterSet.FanSubGroups.GetEnumerator();

            while (e.MoveNext())
            {
                ae.MoveNext();
                if (!IsEqual(e.Current, ae.Current)) return false;
            }


            //Compare Format
            if (!IsEqual(Format, anotherFilterSet.Format)) return false;

            //Compare Resolution
            if (!IsEqual(Resolution, anotherFilterSet.Resolution)) return false;

            
            return true;
        }

        private bool IsEqual(IHasAliases a, IHasAliases b)
        {
            if (a == null && b == null) return true;
            if (a == null && b != null) return false;
            if (a != null && b == null) return false;
            return (a.Name == b.Name);
        }
    }
}
